//
// Created by tang on 2022/10/24.
//

#ifndef LEARNOPENGL_PROGRAM_HPP
#define LEARNOPENGL_PROGRAM_HPP

#include "gl/gl_validation.hpp"
#include <unordered_map>

namespace GL
{
    UNIQUE_HANDLE(Program);

    class Program final {
    public:
        explicit Program(const std::string &name);
        ~Program();

        [[nodiscard]] bool Valid() const;

        void Use() const;
        void NotUse() const;

        void UniformMat4f(const char *name, const glm::mat4 &value);
        void Uniform4f(const char *name, const glm::vec4 &value);
        void Uniform3f(const char *name, const glm::vec3 &value);
        void Uniform2f(const char *name, const glm::vec2 &value);
        void Uniform1f(const char *name, float value);
        void Uniform1i(const char *name, GLint value);

    public:
        FACTORY_METHOD(Program, const std::string &name);

    private:
        GLint FindUniformLocation(const char *name);

        GLuint m_program;
        std::unordered_map<std::string, GLint> m_uniform_location_cache;
    };


}

#endif//LEARNOPENGL_PROGRAM_HPP
